package com.yunyao.web.controller;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.yunyao.common.dto.excel.ContractExcelDto;
import com.yunyao.common.dto.excel.ProjectOrderExcelDto;
import com.yunyao.common.dto.excel.SupplyOrderExcelDto;
import com.yunyao.common.dto.order.ProjectOrderDto;
import com.yunyao.common.dto.order.SupplyOrderDto;
import com.yunyao.common.web.util.PageResult;
import com.yunyao.common.web.util.StringUtils;
import com.yunyao.common.web.util.YResult;
import com.yunyao.framework.dto.file.FileInfoDto;
import com.yunyao.framework.dto.reconciliation.ReconciliationSaveDto;
import com.yunyao.framework.dto.supplyorder.SupplyConsigneeSaveDto;
import com.yunyao.framework.dto.supplyorder.SupplyMaterialSaveDto;
import com.yunyao.framework.dto.supplyorder.SupplyOrderSaveDto;
import com.yunyao.framework.service.SupplyConsigneeService;
import com.yunyao.framework.service.SupplyMaterialService;
import com.yunyao.framework.service.SupplyOrderService;
import com.yunyao.framework.vo.projectorder.ProjectMaterialVO;
import com.yunyao.framework.vo.supplyorder.SupplyConsigneeVO;
import com.yunyao.framework.vo.supplyorder.SupplyMaterialVO;
import com.yunyao.framework.vo.supplyorder.SupplyOrderVO;
import com.yunyao.web.utils.AliOssUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * 供货订单管理
 *
 * @author chenyejian
 * @date 2024-07-16
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/supplyOrder")
public class SupplyOrderController {

    @Autowired
    private SupplyOrderService supplyOrderService;
    @Autowired
    private SupplyMaterialService supplyMaterialService;
    @Autowired
    private SupplyConsigneeService supplyConsigneeService;

    /**
     * 根据条件查询供货订单列表。
     * <p>
     * 通过GET请求访问此方法，可以获取供货订单的分页列表。请求参数包含在SupplyOrderDto对象中，
     * 提供了灵活的查询选项。此方法封装了与服务层的交互，将查询逻辑委托给供货订单服务。
     *
     * @param supplyOrderDto 查询条件对象，包含对供货订单的过滤条件和分页信息。
     * @return 返回一个包含供货订单分页结果的YResult对象。YResult对象封装了操作结果的状态和数据，
     * 其中数据部分是一个PageResult对象，包含了当前页的供货订单列表。
     */
    @GetMapping("/list")
    public YResult<PageResult<SupplyOrderVO>> list(SupplyOrderDto supplyOrderDto) {
        if (!StringUtils.isEmpty(supplyOrderDto.getBeginDate())) {
            supplyOrderDto.setBeginDate(supplyOrderDto.getBeginDate() + " 00:00:00");
        }
        if (!StringUtils.isEmpty(supplyOrderDto.getEndDate())) {
            supplyOrderDto.setEndDate(supplyOrderDto.getEndDate() + " 23:59:59");
        }
        return supplyOrderService.pageList(supplyOrderDto);
    }

    /**
     * 根据订单id查询详情
     */
    @GetMapping("/info")
    public YResult<SupplyOrderVO> detail(SupplyOrderDto supplyOrderDto) {
        if (StringUtils.isEmpty(supplyOrderDto.getId())) {
            return YResult.error("id不能为空");
        }
        return supplyOrderService.getOrderDetailById(supplyOrderDto.getId());
    }


    /**
     * 根据订单id查询材料列表
     */
    @GetMapping("/material/list")
    public YResult<PageResult<SupplyMaterialVO>> materialList(SupplyOrderDto supplyOrderDto) {
        return supplyMaterialService.pageList(supplyOrderDto.getId(),
                supplyOrderDto.getPageIndex(), supplyOrderDto.getPageSize());
    }


    /**
     * 供货功能，根据订单id查询材料列表、包含当前已供货实时查询数量
     */
    @GetMapping("/shipment/material/list")
    public YResult<List<SupplyMaterialVO>> shipmentMaterialList(SupplyOrderDto supplyOrderDto) {
        return supplyMaterialService.hasSupplyMaterialList(supplyOrderDto.getId());
    }


    /**
     * 根据订单id查询收货人
     */
    @GetMapping("/consignee/list")
    public YResult<PageResult<SupplyConsigneeVO>> consigneeList(SupplyOrderDto supplyOrderDto) {
        return supplyConsigneeService.pageList(supplyOrderDto.getId(),
                supplyOrderDto.getPageIndex(), supplyOrderDto.getPageSize());
    }

    /**
     * 保存供货订单
     */
    @PostMapping("/saveOrUpdate")
    public YResult<String> saveOrUpdate(@RequestBody @Validated SupplyOrderSaveDto supplyOrderSaveDto) {
        return supplyOrderService.saveOrUpdate(supplyOrderSaveDto);
    }

    /**
     * 保存订单材料信息
     */
    @PostMapping("/material/saveOrUpdate")
    public YResult<String> materialSaveOrUpdate(@RequestBody SupplyMaterialSaveDto saveDto) {
        return supplyMaterialService.saveOrUpdate(saveDto);
    }


    /**
     * 保存订单收货人
     */
    @PostMapping("/consignee/saveOrUpdate")
    public YResult<String> consigneeSaveOrUpdate(@RequestBody SupplyConsigneeSaveDto saveDto) {
        return supplyConsigneeService.saveOrUpdate(saveDto);
    }

    /**
     * 删除供货订单
     */
    @PostMapping("/deleteByIds")
    public YResult<String> deleteByIds(String[] ids) {
        return supplyOrderService.deleteByIds(ids);
    }

    /**
     * 删除订单材料信息
     */
    @PostMapping("/material/deleteByIds")
    public YResult<String> materialDeleteByIds(String[] ids) {
        return supplyMaterialService.deleteByIds(ids);
    }


    /**
     * 删除订单收货人
     */
    @PostMapping("/consignee/deleteByIds")
    public YResult<String> consigneeDeleteByIds(String[] ids) {
        return supplyConsigneeService.deleteByIds(ids);
    }

    /**
     * 删除供货订单
     */
    @PostMapping("/deleteById")
    public YResult<String> deleteById(@RequestBody SupplyOrderDto dto) {
        String[] ids = new String[1];
        ids[0] = dto.getId();
        return supplyOrderService.deleteByIds(ids);
    }

    /**
     * 删除订单材料信息
     */
    @PostMapping("/material/deleteById")
    public YResult<String> materialDeleteById(@RequestBody SupplyMaterialSaveDto dto) {
        String[] ids = new String[1];
        ids[0] = dto.getId();
        return supplyMaterialService.deleteByIds(ids);
    }

    /**
     * 删除订单收货人
     */
    @PostMapping("/consignee/deleteById")
    public YResult<String> consigneeDeleteByIds(@RequestBody SupplyMaterialSaveDto dto) {
        String[] ids = new String[1];
        ids[0] = dto.getId();
        return supplyConsigneeService.deleteByIds(ids);
    }

    /**
     * 审核供货订单、订单确认
     */
    @PostMapping("/commitAudit")
    public YResult<String> auditOrder(@RequestBody SupplyOrderDto orderDto) {
        return supplyOrderService.audit(orderDto);
    }

    /**
     * 供货
     * @param saveDto
     * @return
     */
    @PostMapping("/save/posupply")
    public YResult<String> saveposupply(@RequestBody SupplyOrderSaveDto saveDto) {
        return supplyOrderService.saveposupply(saveDto);
    }


    /**
     * 根据订单id查询材料列表总和
     */
    @GetMapping("/material/list/count")
    public YResult<SupplyMaterialVO> materialListCount(ProjectOrderDto projectOrderDto) {
        return supplyOrderService.materialListCount(projectOrderDto.getId());
    }

    /**
     * 导出文件
     *
     * @return
     */

    @GetMapping("/export/file")
    public YResult<String> exportFile(SupplyOrderDto supplyOrderDto, HttpServletResponse response) {
        try {
            List<SupplyOrderExcelDto> contractMaterialExportDtoList =  supplyOrderService.export(supplyOrderDto);
            try {
                // 这里URLEncoder.encode可以防止中文乱码
                String fileName = URLEncoder.encode("supplyOrder", String.valueOf(StandardCharsets.UTF_8))+".xlsx";
//                response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
                //设置sheet名
                ExportParams params = new ExportParams();
                params.setSheetName("订单信息模版");
                //设置标题
//                params.setTitle("商品信息");
                // 这里需要设置不关闭流
                Workbook workbook = ExcelExportUtil.exportExcel(params, SupplyOrderExcelDto.class, contractMaterialExportDtoList);
                //输出流
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                workbook.write(bos);
                byte[] bytes = bos.toByteArray();
                bos.close();
                try {
                    FileInfoDto fileInfoDto = AliOssUtil.upload(bytes,
                            fileName, null);
                    if (null != fileInfoDto) {
                        return YResult.success(fileInfoDto.getLink());
                    } else {
                        return YResult.error("连接文件服务器失败，请重试");
                    }
                } catch (Exception e) {
                    return YResult.error("下载失败，请重试");
                }
            } catch (IOException e) {
                System.out.println(e.getMessage());
            }
        }catch (Exception e) {
            log.error("导出订单信息失败",e);
        }
        return YResult.error("导出订单信息失败");
    }
}
